范围及重复
我们经常会遇到要描述一个范围的例子,比如,从 0 到 3 的数字,所有的英文字母, 包含数字,英文字母以及下划线等等,正则表达式规定了如何表示范围:
标志符 | 含义 |
---|---|
[...] | 在集合中的任一个字符 |
[^...] | 不在集合中的任一个字符 |
. |  出\n 之外的任一个字符 |
\w | 所有的单字,包括字母,数字及下划线 |
\W  | 不包括所有的单字,\w 的补集 |
\s | 所有的空白字符,包括空格,制表符 |
\S  |    所有的非空白字符 |
\d | 所有的数字 |
\D |   所有的非数字 |
\b | 退格字符 |
结合元字符和范围,我们可以定义出很强大的模式来,比如,一个简化版的匹配 Email 的正则表达是为:
var emailval = /^[\w-]+(\.[\w-]+)*@[\w-]+(\.[\w-]+)+$/;
emailval.test("kmustlinux@hotmail.com");//true
emailval.test("john.abruzzi@pl.kunming.china");//true
emailval.test("@invalid.com");//false,不合法
[\w-]
表示所有的字符,数字,下划线及减号,[\w-]+
表示这个集合最少重复一次,然后紧接着的这个括号表示一个分组(分组的概念参看下一节),这个分组的修饰符为星号(*
),表示重复零或多次。这样就可以匹配任意字母,数字,下划线及中划线的集合,且至少重复一次。
而@符号之后的部分与前半部分唯一不同的是,后边的一个分组的修饰符为(+
),表示至少重复一次,那就意味着后半部分至少会有一个点号(.
),而且点号之后至少有一个字符。 这个修饰主要是用来限制输入串中必须包含域名。
最后,脱字符(^
)和美元符号($
)限制,以„„开始,且以„„结束。这样,整个表达式的意义就很明显了。
再来看一个例子:在 C/Java 中,变量命名的规则为:以字母或下划线开头,变量中可 以包含数字,字母以及下划线(有可能还会规定长度,我们在下一节讨论)。这个规则描述成正则表达式即为下列的定义:
var variable = /[a-zA-Z_][a-zA-Z0-9_]*/;
print(variable.test("hello"));
print(variable.test("world"));
print(variable.test("_main_"));
print(variable.test("0871"));
将会打印:
true
true
true
false
前三个测试字符均为合法,而最后一个是数字开头,因此为非法。应该注意的是,test 方法只是测试目标串中是否有表达式匹配的部分,而不一定整个串都匹配。比如上例中:
print(variable.test("0871_hello_world"));//true
print(variable.test("@main"));//true
同样返回 true,这是因为,test 在查找整个串时,发现了完整匹配 variable 表达式的部分 内容,同样也是匹配。为了避免这种情况,我们需要给 variable 做一些修改:
var variable = /^[a-zA-Z_][a-zA-Z0-9_]*$/;
通过加推导(+),星推导(*),以及谓词,我们可以灵活的对范围进行重复,但是我们仍然需要一种机制来提供诸如 4 位数字,最多 10 个字符等这样的精确的重复方式。这就需要用 到下表中的标记: |标记 |含义 |-----| |{n} |重复n次 |{n,} |重复 n 或更多次 |{n,m} |重复至少n次,至多m次
有了精确的重复方式,我们就可以来表达如身份证号码,电话号码这样的表达式,而不用担心出做,比如:
var pid = /^(\d{15}|\d{18})$/;//身份证
var mphone = /\d{11}/;//手机号码
var phone = /\d{3,4}-\d{7,8}/;//电话号码
mphone.test("13893939392");//true
phone.test("010-99392333");//true
phone.test("0771-3993923");//true
{$ activeFileHint $}